using System;
using System.Drawing;
using System.Windows.Forms;
using needle.UI.Controls.Flat.Windows.Forms;

namespace needle.UI.Controls.Flat.Windows.Docking
{
    public class HotZoneReposition : HotZone
    {
		#region Nested types

		protected enum Position
        {
            Inner,
            Index,
            Outer
        }

		#endregion

        protected int mnewIndex;
        protected Position mposition;
        protected State mstate;

		#region Constructors
		
		public HotZoneReposition(Rectangle hotArea, Rectangle newSize, State state, bool inner)
            : base(hotArea, newSize)
        {
            InternalConstruct((inner ? Position.Inner : Position.Outer), state, -1);
        }

        public HotZoneReposition(Rectangle hotArea, Rectangle newSize, State state, int newIndex)
            : base(hotArea, newSize)
        {
            InternalConstruct(Position.Index, state, newIndex);
        }

        protected void InternalConstruct(Position position, State state, int newIndex)
        {
            mposition = position;
            mnewIndex = newIndex;
            mstate = state;
        }

		#endregion

		#region Overrides

        public override bool ApplyChange(Point screenPos, Redocker parent)
        {
            RedockerContent redock = parent as RedockerContent;

            DockingManager dockingManager = redock.DockingManager;

            dockingManager.Container.SuspendLayout();

            Zone zone;
            
            if (redock.DockingSource == RedockerContent.Source.FloatingForm)
			{
				redock.FloatingForm.ExitFloating();

                zone = redock.FloatingForm.Zone;
			}
            else
                zone = dockingManager.CreateZoneForContent(mstate);

            dockingManager.Container.Controls.Add(zone);

            switch(mposition)
            {
                case Position.Inner:
                    dockingManager.ReorderZoneToInnerMost(zone);
                    break;
                case Position.Index:
                    dockingManager.RemoveShowingAutoHideWindows();
                
                    dockingManager.Container.Controls.SetChildIndex(zone, mnewIndex + 1);
                    break;
                case Position.Outer:
                    dockingManager.ReorderZoneToOuterMost(zone);
                    break;
            }

            switch(redock.DockingSource)
            {
                case RedockerContent.Source.RawContent:
                    {
                        Window w = dockingManager.CreateWindowForContent(redock.Content);
                        
                        zone.Windows.Add(w);
                    }
                    break;
                case RedockerContent.Source.WindowContent:
                    if (redock.WindowContent.ParentZone != null)
                    {
                        if (redock.WindowContent.State == State.Floating)
                        {
                            foreach(Content c in redock.WindowContent.Contents)
                                c.ContentLeavesFloating();
                        }
                        
                        redock.WindowContent.ParentZone.Windows.Remove(redock.WindowContent);
                    }

                    zone.Windows.Add(redock.WindowContent);
                    break;
                case RedockerContent.Source.ContentInsideWindow:
                    {
                        if (redock.Content.ParentWindowContent != null)
                        {
                            if (redock.Content.ParentWindowContent.State == State.Floating)
                                redock.Content.ContentLeavesFloating();

                            redock.Content.ParentWindowContent.Contents.Remove(redock.Content);
                        }
    				
                        Window w = dockingManager.CreateWindowForContent(redock.Content);

                        zone.Windows.Add(w);
                    }
                    break;
                case RedockerContent.Source.FloatingForm:
                    DockStyle ds;
                    Direction direction;
                
                    dockingManager.ValuesFromState(mstate, out ds, out direction);

                    zone.Dock = ds;
                    
                    ZoneSequence zs = zone as ZoneSequence;
                    
                    if (zs != null)
                        zs.Direction = direction;

                    zone.State = mstate;
                    break;
            }

            switch(mstate)
            {
                case State.DockLeft:
                case State.DockRight:
                    zone.Width = mnewSize.Width;
                    break;
                case State.DockTop:
                case State.DockBottom:
                    zone.Height = mnewSize.Height;
                    break;
            }

			dockingManager.UpdateInsideFill();

            dockingManager.Container.ResumeLayout();

            return true;
        }

		#endregion
    }
}